package app;

import datastructure.Instance;
import datastructure.Solution;

public class DataRecord {
    int divide = 0;
    int numofCustomer = 0;
    int numofPFC = 0;
    int numofTask = 0;

    double a = 0;
    double b = 0;
    double Len = 0;

    double c1 = 0;
    double c2 = 0;
    double miu = 0;

    double Fi = 0;
    double Fm = 0;
    double[] delta;


    double[][] distanceMatrix;
    int[][] ODdemand;

    double[][] coordinateofPFC;
    double[][] coordinateofCustomer;
    double[][] coordinate;
    int experimentnumber = 0;
    String time;
    double Transcost = 0;
    double FuelOPT = 0;

    int[] ODdemandSequ;
    int[][] ODflow;
    double[] CapaODOPTpast;
    int[][] IterModeOPTpast;
    int[] FirstIterOPTpast;
    int[][] MODErevise;

    public DataRecord(Instance instance, int experimentnumber, String time) {
        this.numofPFC = instance.numofPFC;
        this.divide = instance.divide;
        this.numofCustomer = instance.numofCustomer;
        this.numofTask = instance.numofTask;
        this.a = instance.a;
        this.b = instance.b;
        this.Len = instance.Len; //
        this.c1 = instance.c1;
        this.c2 = instance.c2;
        this.miu = instance.miu;
        this.Fi = instance.Fi;
        this.Fm = instance.Fm;
        this.delta = instance.delta;
        this.ODdemand = instance.ODdemand;
        this.distanceMatrix = instance.distanceMatrix;
        this.coordinateofPFC = instance.coordinateofPFC;
        this.coordinateofCustomer = instance.coordinateofCustomer;
        this.experimentnumber = experimentnumber;
        this.time = time;

    }

    public void data(Solution solution) {
        this.FirstIterOPTpast = solution.FirstIterOPTpast;
        this.CapaODOPTpast = solution.CapaODOPTpast;
        this.IterModeOPTpast = solution.IterModeOPTpast;
        this.ODdemandSequ = solution.ODdemandSequ;
        this.ODflow = solution.ODflow;
        this.Transcost = solution.Transcost;
        this.MODErevise = solution.MODErevise;
        ;

        System.out.println("--------------------------------------");
        int temp1 = 0;
        double temp2 = 0;
        double temp3 = 0;
        for (int i = 0; i < numofCustomer; i++) {
            for (int j = 0; j < numofCustomer; j++) {
                temp1 = ODdemand[i][j] + temp1;
                temp2 = (c1 + c2 * miu) * ODdemand[i][j] * distanceMatrix[i][j] + temp2;
                temp3 = miu * ODdemand[i][j] * distanceMatrix[i][j] + temp3;
            }
        }

        for (int i = 0; i < ODdemandSequ.length; i++) {
            if (IterModeOPTpast[i][0] > 0) {
                FuelOPT = miu * ODdemandSequ[i] * (distanceMatrix[ODflow[i][0]][(numofCustomer + IterModeOPTpast[i][0] - 1)] + distanceMatrix[(numofCustomer + IterModeOPTpast[i][1] - 1)][ODflow[i][1]]) +
                        miu * ODdemandSequ[i] * distanceMatrix[(numofCustomer + IterModeOPTpast[i][0] - 1)][(numofCustomer + IterModeOPTpast[i][1] - 1)] * ((1 - a) + (Len - 1) * (1 - b)) / Len + FuelOPT;
            } else {
                FuelOPT = miu * ODdemandSequ[i] * distanceMatrix[ODflow[i][0]][ODflow[i][1]] + FuelOPT;
            }
        }
        System.out.println("final_value:" + Transcost);
        System.out.println("final_fuel:" + FuelOPT);

        System.out.println("--------------------------------------");
        System.out.println("traditional_value：" + temp2);
        System.out.println("traditional_fuel：" + temp3);
        System.out.println("--------------------------------------");


        int PFCrecord = 0;
        for (int i = 0; i < numofPFC; i++) {
            if (FirstIterOPTpast[i] > 0) {
                PFCrecord++;
            }
        }
        System.out.println("number_PFC:" + PFCrecord);
        int temp5 = 0;
        for (int i = 0; i < CapaODOPTpast.length; i++) {
            if ((CapaODOPTpast[i] < Fi) && (FirstIterOPTpast[i] > 0)) {
                temp5++;
            }
        }
        System.out.println("Tm_PFC:" + temp5);
        System.out.println("PFC_construct_rate:" + (double) PFCrecord / (double) numofPFC);
        double temp4 = 0;
        for (int i = 0; i < ODdemandSequ.length; i++) {
            if (IterModeOPTpast[i][0] > 0) {
                temp4 = temp4 + ODdemandSequ[i];
            }
        }
        System.out.println("OD_PFC_rate：" + temp4 / temp1);

        double temp6 = 0;
        for (int i = 0; i < ODdemandSequ.length; i++) {
            if (IterModeOPTpast[i][0] > 0) {
                double t1 = (c1 + c2 * miu) * ODdemandSequ[i] * distanceMatrix[ODflow[i][0]][ODflow[i][1]];
                double t2 = (c1 + c2 * miu) * ODdemandSequ[i] * (distanceMatrix[ODflow[i][0]][(numofCustomer + IterModeOPTpast[i][0] - 1)] + distanceMatrix[(numofCustomer + IterModeOPTpast[i][1] - 1)][ODflow[i][1]]) +
                        c2 * miu * ODdemandSequ[i] * distanceMatrix[(numofCustomer + IterModeOPTpast[i][0] - 1)][(numofCustomer + IterModeOPTpast[i][1] - 1)] * ((1 - a) + (Len - 1) * (1 - b)) / Len +
                        c1 * ODdemandSequ[i] / Len * distanceMatrix[(numofCustomer + IterModeOPTpast[i][0] - 1)][(numofCustomer + IterModeOPTpast[i][1] - 1)];
                temp6 = temp6 + (t1 - t2) / (t1);
            }
        }
        System.out.println("OD_save：" + temp6 / ODdemandSequ.length);

        double[][] PFCPreference = new double[numofPFC][numofPFC];

        for (int i = 0; i < ODdemandSequ.length; i++) {
            if (IterModeOPTpast[i][0] > 0) {
                PFCPreference[IterModeOPTpast[i][0] - 1][IterModeOPTpast[i][1] - 1] = PFCPreference[IterModeOPTpast[i][0] - 1][IterModeOPTpast[i][1] - 1] + ODdemandSequ[i];
            }
        }

        for (int i = 0; i < numofPFC; i++) {
            for (int j = 0; j < numofPFC; j++) {
                if ((i != j) && (FirstIterOPTpast[i] > 0) && (FirstIterOPTpast[j] > 0)) {
                    double temp7 = PFCPreference[i][j];
                    PFCPreference[i][j] = (c1 + c2 * miu) * PFCPreference[i][j] * distanceMatrix[i + numofCustomer][j + numofCustomer] -
                            c2 * miu * (PFCPreference[i][j] / Len) * distanceMatrix[i + numofCustomer][j + numofCustomer] * ((1 - a) + (Len - 1) * (1 - b)) -
                            c1 * (PFCPreference[i][j] / Len) * distanceMatrix[i + numofCustomer][j + numofCustomer];
                    if (CapaODOPTpast[i] < Fi) {
                        PFCPreference[i][j] = PFCPreference[i][j] - ((temp7 / CapaODOPTpast[i]) * Fi * delta[i]);
                    } else {
                        PFCPreference[i][j] = PFCPreference[i][j] - temp7 * delta[i];
                    }
                    if (CapaODOPTpast[j] < Fi) {
                        PFCPreference[i][j] = PFCPreference[i][j] - ((temp7 / CapaODOPTpast[j]) * Fi * delta[j]);
                    } else {
                        PFCPreference[i][j] = PFCPreference[i][j] - temp7 * delta[j];
                    }
                }
            }
        }

        System.out.println("--------------------------------------");
        System.out.println("total_OD：" + temp1);

    }

}
